package com.hbx.task;

import com.hbx.constant.RspEnum;
import com.hbx.exception.RspException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;

import java.time.Duration;

/*
 * @Author:hbx
 *
 * */
@Slf4j
public abstract class BaseJob<T> {

    private static final int TIME_OUT = 60;

    private static final int RETRY_TIME = 3;

    @Autowired
    private RedisTemplate<String,Object> template;


    public void execute() {
        ScheduledJobEnum scheduledJob = getScheduledJobEnum();
        log.info("execute start job:{}", scheduledJob);
        // 前置检查
        if (beforeExecute()){
            String lockKey = scheduledJob.getLockKey();
            if (StringUtils.isEmpty(lockKey)) {
                log.info("scheduledJob :{} ", scheduledJob);
                throw new RspException(RspEnum.JOB_IS_ULL);
            }
            try {
                Boolean lock = template.opsForValue().setIfAbsent(lockKey,
                        lockKey, Duration.ofSeconds(TIME_OUT));
                if (!lock) {
                    log.error("get redis dlock error, lock:{}, job:{}", lock.toString(), scheduledJob);
                    // 动态接口不受影响, 返回AUTH_ERROR
                    throw new RspException(RspEnum.JOB_IS_ULL);
                }
                doExecute();
                afterExecute();
            } catch (Exception e) {
                onException(e);
                e.printStackTrace();
                throw e;
            } finally {
                template.delete(lockKey);
            }
        }
    }

    public abstract ScheduledJobEnum getScheduledJobEnum();

    public abstract Boolean beforeExecute();

    public abstract void doExecute();

    public abstract void afterExecute();

    /**
     * 异理处理
     * @param e
     */
    public void onException(Exception e) {
        log.error("job run error, jobEnum: {}", this.getScheduledJobEnum(), e);
    }
}
